﻿using System;
using Ninject;
using Reactor.Contracts;

namespace Reactor.Container.Ninject
{
    public class NinjectServiceRegistrar : IServiceRegistrar
    {
        private readonly IKernel _kernel;

        /// <summary>
        /// Initializes a new instance of the <see cref="NinjectServiceRegistrar"/> class.
        /// </summary>
        /// <param name="kernel">The kernel.</param>
        public NinjectServiceRegistrar(IKernel kernel)
        {
            if (kernel == null) throw new ArgumentNullException("kernel");

            _kernel = kernel;
        }

        #region Implementation of IServiceRegistrar

        /// <summary>
        /// Registers a single instance that is to be returned when the specified type is requested..
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instance">The instance.</param>
        public void RegisterInstance<T>(object instance) where T : class
        {
            _kernel.Bind<T>().ToConstant((T) instance);
        }

        /// <summary>
        /// Registers the a concrete type to associate with the abstract type.
        /// </summary>
        /// <typeparam name="T">Abstract type</typeparam>
        /// <typeparam name="TConcrete">The concrete type to instantiate when the abstract type is requested.</typeparam>
        public void RegisterType<T, TConcrete>() where TConcrete : T
        {
            _kernel.Bind<T>().To<TConcrete>();
        }

        #endregion
    }
}
